import os
import sys
import time

sys.path.insert(0, os.path.expanduser('~') + '/lib/python')

from mylib.server import MyServer
from mylib.timer import ThreadTimer

try: import Tkinter as tk  # Python 2
except ImportError: import tkinter as tk  # Python 3

info = '''alarm 0.1.0
    > alarm at 12:13:00
    > alarm after 12:13:00
'''


class AlarmItem:
    _type = 'at'
    _datetime_str = '0000/00/00 00:00:00'
    _datetime = 0.0
    _alarm = 'once'  # once, every [hour, day, week, month]
    _enable = False

    def set_time(self, tm):
        self._datetime = tm

    def get_time(self):
        return self._datetime

    def get_time_str(self):
        return time.strftime('%Y/%m/%d %T', time.localtime(self._datetime))

    def diff_time(self, tm):
        return self._datetime - tm

    def diff_time_str(self, tm):
        _diff = self.diff_time(tm)
        _sec = _diff
        _min = 0
        _hour = 0
        _day = 0

        if _diff > 60.0:
            _diff, _sec = divmod(_diff, 60.0)
            if _diff > 60.0:
                _diff, _min = divmod(_diff, 60.0)
                if _diff > 24.0:
                    _day, _hour = divmod(_diff, 24.0)

        return str("%d %02d:%02d:%02d" % (int(_day), int(_hour), int(_min), int(_sec)))


class AlarmApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        self.text = tk.Text(self)
        self.text.pack(side="top", fill="both", expand=True)
        self.listbox = tk.Listbox(self)
        self.listbox.pack(side="bottom", fill="both", expand=True)
        self.svr = MyServer()
        self.svr.set_recv(self.socket_recv)
        self.svr.start('', 24069)
        self.timer = ThreadTimer(1, self.on_timer)
        self.timer.start()
        self.alarm = []

    def exit(self, event=None):
        self.timer.stop()
        self.svr.stop()
        time.sleep(0.1)

    def socket_recv(self, sock, data):
        print(data)
        self.add_alarm(data)
        sock.send(data.encode('utf-8'))

    def parse_str_to_alarm_item(self, arg):
        itm = AlarmItem()
        args = arg.split()
        for s in args:
            s = s.lower()
            if s.startswith('at'): itm._type = 'at'
            if s.startswith('after'): itm._type = 'after'
            if s.startswith('once'): itm._alarm = 'once'
            if s.startswith('every'): itm._alarm = 'every'
            if s.startswith('day'): itm._alarm += ' day'
        return itm

    def add_alarm(self, arg):
        itm = AlarmItem()
        itm.set_time(time.time() + 30)
        self.alarm.append(itm)

    def append(self, line):
        tm = time.strftime('%Y-%m-%d %T> ', time.localtime())
        self.listbox.insert('end', tm + line)
        while self.listbox.size() > 25:
            self.listbox.delete(0)
        self.listbox.see('end')

    def on_timer(self):
        for itm in self.alarm:
            tm = itm.diff_time_str(time.time())
            self.append(tm)


def main(argv):
    """Entry point for demo manager"""
    app = AlarmApp()
    app.add_alarm(' '.join(argv))
    app.mainloop()
    app.exit()


def connect_alarm():
    import socket
    __PORT = 24069    # Arbitrary non-privileged port
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    try: s.connect(('', __PORT))  # Symbolic name meaning the local host
    except: return False, None
    return True, s


def send_alarm(_sock, line):
    _sock.send(bytes(line, 'utf-8'))
    reply = _sock.recv(1024)
    print('recv : ', reply.decode('utf-8'))
    _sock.close()

if __name__ == '__main__':
    print(info)
    path = os.getcwd()
    argc = len(sys.argv)
    argv = ''
    if argc > 1:
        argv = ' '.join(sys.argv[1:])
        connected, sock = connect_alarm()
        if connected:
            send_alarm(sock, argv)
            exit()

    main(argv)

